package UMC.Web;

import UMC.Data.Utility;
import UMC.Security.AccessToken;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Map;

public class WebContext {
    WebRuntime runtime;

    public AccessToken token() {
        return runtime.client.accessToken;
    }

    public WebRequest request() {
        return runtime.request;
    }

    public WebResponse response() {
        return runtime.response;
    }

    protected void complete() {

    }

    public WebActivity activity() {
        return runtime._activity;
    }

    public WebFlow flow() {
        return runtime._flow;
    }


    /**
     * 数据共享数据
     *
     * @return
     */
    public Map<String, Object> items() {
        return runtime.client._items;
    }

    protected WebContext(WebRuntime webRuntime) {
        this.runtime = webRuntime;
    }


    /**
     * 终止流程
     */
    public void end() {
        throw new WebRuntime.AbortException();
    }

    /**
     * 发送数据到客户端
     *
     * @param data        数据
     * @param endResponse 是否终止后面处理
     */
    public void send(WebMeta data, boolean endResponse) {
        if (data.containsKey("type") == false) {
            data.put("type", String.format("%s.%s", runtime.request._model, runtime.request._cmd));
        }
        sendJSON(data, endResponse);
    }

    void sendJSON(UMC.Data.IJSON json, boolean endResponse) {
        WebResponse response = this.response();
        response.ClientEvent |= WebEvent.DATAEVENT;
        if (response.Headers.containsKey("DataEvent")) {
            Object ts = response.Headers.map().get("DataEvent");
            if (ts.getClass().isArray()) {
                Object[] mts = new Object[Array.getLength(ts) + 1];
                Arrays.copyOf(mts, mts.length - 2);
                mts[mts.length - 1] = json;
                response.Headers.put("DataEvent", mts);
            } else {
                response.Headers.put("DataEvent", new Object[]{ts, json});
            }

        } else {

            response.Headers.put("DataEvent", json);
        }
        if (endResponse) {
            this.end();
        }

    }

    /**
     * 发送界面响应事件
     *
     * @param name        界面事件
     * @param value       参数
     * @param endResponse 是否终止
     */
    public void event(String name, Object value, boolean endResponse) {
        this.send(new WebMeta().put("key", name).put("value", value), endResponse);
    }

    /**
     * 发送界面响应事件
     *
     * @param name        界面事件
     * @param ui          接收界面
     * @param value       参数
     * @param endResponse 是否终止
     */
    public void event(String name, String ui, Object value, boolean endResponse) {

        switch (Utility.isNull(ui, "none")) {
            case "none":
                this.UIEvent(new WebMeta().put("key", name).put("value", value), endResponse);
                break;
            default:
                this.UIEvent(new WebMeta().put("key", name).put("ui", ui).put("value", value), endResponse);
                break;
        }
    }

    private void UIEvent(WebMeta webMeta, boolean end) {
        this.runtime.response.Headers.put("UIEvent", webMeta);
        this.runtime.response.ClientEvent = this.runtime.response.ClientEvent | WebEvent.UIEvent;
        if (end)
            this.runtime.response.end();
    }

    /**
     * 发送数据事件到客户端
     *
     * @param type        数据事件类型
     * @param data        数据
     * @param endResponse 是否终止后面处理
     */
    public void send(String type, WebMeta data, boolean endResponse) {
        this.send(data.put("type", type), endResponse);
    }

    /**
     * 发送数据事件到客户端
     *
     * @param type        数据事件类型
     * @param endResponse 是否终止后面处理
     */
    public void send(String type, boolean endResponse) {
        send(new WebMeta().put("type", type), endResponse);
    }

    /**
     * 发送数据事件到客户端
     *
     * @param click       数据事件类型
     * @param endResponse 是否终止后面处理
     */
    public void send(UIClick click, boolean endResponse) {
        send(new WebMeta().put("type", "Click").put("Click", click), endResponse);
    }

    /**
     * 重置主界面
     */
    public void reset() {

        this.response().ClientEvent |= WebEvent.RESET;
    }

    /**
     * 重置界面
     *
     * @param meta 界面数据
     */
    public void reset(WebMeta meta) {
        WebResponse response = this.response();
        response.ClientEvent |= WebEvent.RESET;
        response.Headers.put("Reset", meta);
    }

    /**
     * 发送界面关闭事件
     */
    public void close() {
        this.response().ClientEvent |= WebEvent.CLOSE;
    }

}
